package com.mazaiting.rtda;

import cn.hutool.core.util.ObjectUtil;

/**
 * 栈
 *
 * @author mazaiting
 * @since 2021/8/13
 */
public class MtStack {
    /**
     * 最大栈容量
     */
    private final long maxSize;
    /**
     * 当前栈大小
     */
    private long size;
    /**
     * 当前栈帧
     */
    private MtFrame topFrame;

    public MtStack(int maxSize) {
        this.maxSize = maxSize;
    }

    /**
     * 入栈
     * @param frame 栈帧
     */
    public void push(MtFrame frame) {
        if (size >= maxSize) {
            throw new RuntimeException("java.lang.StackOverflowError");
        }
        // 如果栈顶不为空, 则赋值引用
        if (ObjectUtil.isNotNull(topFrame)) {
            frame.lower = topFrame;
        }
        // 设置栈顶元素
        this.topFrame = frame;
        // 当前容量+1
        this.size++;
    }

    /**
     * 弹出栈帧
     * @return 栈帧
     */
    public MtFrame pop() {
        if (ObjectUtil.isNull(topFrame)) {
            throw new RuntimeException("jvm stack is empty!");
        }
        // 出栈
        MtFrame tmpFrame = topFrame;
        this.topFrame = tmpFrame.lower;
        // 清空引用, 以便于垃圾回收器回收
        tmpFrame.lower = null;
        // 出栈后长度-1
        this.size--;
        return tmpFrame;
    }

    /**
     * 返回当前栈帧
     * @return 当前栈帧
     */
    public MtFrame top() {
        if (ObjectUtil.isNull(topFrame)) {
            throw new RuntimeException("jvm stack is empty!");
        }
        return topFrame;
    }
}


















